package android_serialport_api;

import android.util.Log;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class SerialPortManager {

    SerialPort serialPort;
    public List<OnDataReceiveListener> observable;
    SerialPortReadThread serialPortReadThread;
    private LinkedBlockingQueue<byte[]> queue = new LinkedBlockingQueue<>();


    Executor executor = Executors.newSingleThreadExecutor();

    private FileInputStream mFileInputStream; //    读取流   从底层读取数据
    private FileOutputStream mFileOutputStream;//    写入流  传递信息

    public void putCommand(byte[] command) {
        try {
            queue.put(command);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    private Runnable taskCenterRunnable = new Runnable() {
        @Override
        public void run() {
            while (true) {

                byte[] content = null;
                try {
                    content = queue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (content != null) {
                    try {
                        mFileOutputStream.write(content);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    };


    public SerialPortManager() {
        observable = new ArrayList<>();

    }


    //观察者模式----------------------------------------->
    public void regist(OnDataReceiveListener protDataInterface) {
        if (protDataInterface != null) {
            observable.add(protDataInterface);
        }
    }

    public void unregist(OnDataReceiveListener protDataInterface) {
        if (protDataInterface != null) {
            observable.remove(protDataInterface);
        }
    }

    public void update(byte[] content) {
        for (OnDataReceiveListener protDataInterface : observable) {
            protDataInterface.onDataReceive(content);
        }
    }

    public void close() {
        serialPort.close();
    }

    public void openSerialPort(String path, int baudRate) {

        File file = new File(path);

        try {
            if (serialPort != null) {
                serialPort.close();
            }
            serialPort = new SerialPort(file, baudRate, 0);
            mFileInputStream = serialPort.getInputStream();
            mFileOutputStream = serialPort.getOutputStream();


            if (mFileInputStream != null && mFileOutputStream != null) {
                startReadThread();
                executor.execute(taskCenterRunnable);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    private void startReadThread() {
        if (serialPortReadThread != null) {
            serialPortReadThread.setInterrupted(true);
            serialPortReadThread.interrupt();
            serialPortReadThread = null;

        }
        serialPortReadThread = new SerialPortReadThread(mFileInputStream) {
            @Override
            public void onDataReceived(byte[] readBytes) {
                update(readBytes);
            }
        };
        serialPortReadThread.start();
    }


}
